package com.framework.bdf4j.comm.web;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.util.WebUtils;

import com.framework.bdf4j.comm.Constants;
import com.framework.bdf4j.comm.util.ClassUtils;

import cn.hutool.json.JSONUtil;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

/**
 * <b>文件名： </b>WebUtil.java<br/>
 * <b>类描述： </b>Web层辅助类<br/>
 */
@Slf4j
@UtilityClass
public class WebUtil extends WebUtils {

    /**
     * <b>方法描述：</b> 获取指定Cookie的值 <br/>
     *
     * @param request
     *            request请求
     * @param cookieName
     *            cookie名字
     * @param defaultValue
     *            缺省值
     * @return cookie值
     */
    public static String getCookieValue(HttpServletRequest request, String cookieName, String defaultValue) {
        Cookie cookie = getCookie(request, cookieName);
        if (cookie == null) {
            return defaultValue;
        }
        return cookie.getValue();
    }

    /**
     * 判断是否ajax请求 spring ajax 返回含有 ResponseBody 或者 RestController注解
     *
     * @param handlerMethod
     *            HandlerMethod
     * @return 是否ajax请求
     */
    public boolean isBody(HandlerMethod handlerMethod) {
        ResponseBody responseBody = ClassUtils.getAnnotation(handlerMethod, ResponseBody.class);
        return responseBody != null;
    }

    /**
     * 读取cookie
     *
     * @param name
     *            cookie name
     * @return cookie value
     */
    public String getCookieVal(String name) {
        HttpServletRequest request = WebUtil.getRequest();
        Assert.notNull(request, "request from RequestContextHolder is null");
        return getCookieVal(request, name);
    }

    /**
     * 读取cookie
     *
     * @param request
     *            HttpServletRequest
     * @param name
     *            cookie name
     * @return cookie value
     */
    public String getCookieVal(HttpServletRequest request, String name) {
        Cookie cookie = getCookie(request, name);
        return cookie != null ? cookie.getValue() : null;
    }

    /**
     * 清除 某个指定的cookie
     *
     * @param response
     *            HttpServletResponse
     * @param key
     *            cookie key
     */
    public void removeCookie(HttpServletResponse response, String key) {
        setCookie(response, key, null, 0);
    }

    /**
     * 设置cookie
     *
     * @param response
     *            HttpServletResponse
     * @param name
     *            cookie name
     * @param value
     *            cookie value
     * @param maxAgeInSeconds
     *            maxage
     */
    public void setCookie(HttpServletResponse response, String name, String value, int maxAgeInSeconds) {
        Cookie cookie = new Cookie(name, value);
        cookie.setPath("/");
        cookie.setMaxAge(maxAgeInSeconds);
        cookie.setHttpOnly(true);
        response.addCookie(cookie);
    }

    /**
     * 获取 HttpServletRequest
     *
     * @return {HttpServletRequest}
     */
    public HttpServletRequest getRequest() {
        return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
    }

    /**
     * 获取 HttpServletResponse
     *
     * @return {HttpServletResponse}
     */
    public HttpServletResponse getResponse() {
        return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();
    }

    /**
     * 返回json
     *
     * @param response
     *            HttpServletResponse
     * @param result
     *            结果对象
     */
    public void renderJson(HttpServletResponse response, Object result) {
        renderJson(response, result, MediaType.APPLICATION_JSON_VALUE);
    }

    /**
     * 返回json
     *
     * @param response
     *            HttpServletResponse
     * @param result
     *            结果对象
     * @param contentType
     *            contentType
     */
    public void renderJson(HttpServletResponse response, Object result, String contentType) {
        response.setCharacterEncoding("UTF-8");
        response.setContentType(contentType);
        try (PrintWriter out = response.getWriter()) {
            out.append(JSONUtil.toJsonStr(result));
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }

    /** 获取当前用户 */
    public static Integer getHttpCurrentUserId() {
        try {
            HttpServletRequest httpRequest = getRequest();
            if (httpRequest != null) {
                HttpSession session = getRequest().getSession();
                if (null != session) {
                    return (Integer)session.getAttribute(Constants.CURRENT_USERID);
                }
            }
        } catch (Exception e) {
            // log.error(e.getMessage(), e);
        }
        return null;
    }

    public static String getHttpCurrentUserName() {
        try {
            HttpServletRequest httpRequest = getRequest();
            if (httpRequest != null) {
                HttpSession session = getRequest().getSession();
                if (null != session) {
                    return (String)session.getAttribute(Constants.CURRENT_USERNAME);
                }
            }
        } catch (Exception e) {
            // log.error(e.getMessage(), e);
        }
        return "";
    }

    /** 保存当前用户 */
    public static void saveHttpCurrentUserId(Integer userId) {
        setHttpSession(Constants.CURRENT_USERID, userId);
    }

    /** 保存当前用户的部门ID */
    public static void saveHttpCurrentUserDeptId(Integer deptId) {
        setHttpSession(Constants.CURRENT_DEPTID, deptId);
    }

    /** 保存当前用户的角色信息 */
    public static void saveHttpCurrentRoles(List<Integer> rolelist) {
        setHttpSession(Constants.CURRENT_ROLELIST, rolelist);
    }

    /** 获取当前用户的角色信息 */
    @SuppressWarnings("unchecked")
    public static List<Integer> getHttpCurrentRoles() {
        try {
            HttpServletRequest httpRequest = getRequest();
            if (httpRequest != null) {
                HttpSession session = getRequest().getSession();
                if (null != session) {
                    return (List<Integer>)session.getAttribute(Constants.CURRENT_ROLELIST);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    /** 获取当前用户的部门ID */
    public static Integer getHttpCurrentUserDptId() {
        try {
            HttpServletRequest httpRequest = getRequest();
            if (httpRequest != null) {
                HttpSession session = getRequest().getSession();
                if (null != session) {
                    return (Integer)session.getAttribute(Constants.CURRENT_DEPTID);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    /**
     * <b>方法描述：</b> 保存数据到HttpSession中 <br/>
     *
     * @param key
     * @param value
     */
    public static void setHttpSession(String key, Object value) {
        HttpSession session = getRequest().getSession();
        if (null != session) {
            session.setAttribute(key, value);
        }
    }

    /**
     * <b>方法描述：</b> 获取HttpSession中的数据 <br/>
     *
     * @param key
     * @return
     */
    public static Object getHttpSession(String key) {
        Object obj = null;
        HttpSession session = getRequest().getSession();
        if (null != session) {
            obj = session.getAttribute(key);
        }
        return obj;
    }

    /**
     * 获取ip
     *
     */
    public String getHost() {
        HttpServletRequest request = getRequest();
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Forwarded-For");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return StringUtils.isBlank(ip) ? null : ip.split(",")[0];
    }
}
